﻿namespace NKernel.Core
{
    using System.Collections.Generic;

    /// <summary>
    /// NKernel components are assumed to have the following lifecycle: (1) initialisation, (2) start, 
    /// (3) stop and (4) cleanup.
    /// </summary>
    //TODO - Embed the 2 resource files
    //TODO - Add NetMx support
    //TODO - figure how Windsor processes generic interfaces as string values
    //TODO - Component descriptor must support multiple interfaces within the same logical component
    //TODO - Add a scripting engine to dynamically create objects for injection
    public interface IKernel
    {
        #region Methods

        /// <summary>
        /// Cleans up or releases all the resources prior to application cessation
        /// Default method used for invocation is 'Cleanup'
        /// Methods must have this signature 'public void Cleanup()'
        /// </summary>
        /// <returns></returns>
        KernelResult Cleanup();

        /// <summary>
        /// 
        /// </summary>
        /// <returns>List of instantiated component objects</returns>
        IList<IComponentObject> GetComponents();

        /// <summary>
        /// Accessor method to get the implementation of an interface
        /// </summary>
        /// <typeparam name="T">Fully-qualified name of the interface type</typeparam>
        /// <returns>interface instance object</returns>
        T GetInstance<T>();

        /// <summary>
        /// Initialises all the components
        /// Default method used for invocation is 'Init'
        /// Methods must have this signature 'public void Init()'
        /// </summary>
        /// <returns></returns>
        KernelResult Init();

        /// <summary>
        /// If there are any components that have greater priority in terms of lifecycle management (e.g., init and start),
        /// then this method should be invoked prior to other Manage, Load, Init and Start methods.
        /// The index position also indicates the priority for component initialisation and start.
        /// Conversely, during application cleanup and stop lifecycle, the order will be reversed - namely,
        /// the tail end of the queue will be the first to have their cleanup method applied and the same down the line until
        /// the head of the queue is reached. Similarly, the same procedure will be applied for the stop lifecycle method.
        /// </summary>
        /// <param name="priorityComponents">logical component names or regular expressions for component names</param>
        /// <seealso cref="Manage(string[])"/>
        /// <seealso cref="Init"/>
        /// <example>new [] { "Component.Name", "Component.*" }</example>
        void InitPriorityList(string[] priorityComponents);

        /// <summary>
        /// Method to load all the components from a specified location
        /// The components are assumed to use the suffix '.DLL'
        /// </summary>
        /// <param name="componentLocations">file locations of the folder containing the components</param>
        /// <returns></returns>
        KernelResult Load(string[] componentLocations);

        /// <summary>
        /// Method to load all the components from the default location
        /// The components are assumed to use the suffix '.DLL'
        /// </summary>
        KernelResult Load();

        /// <summary>
        /// Convenience method to load, initialise and start the components found 
        /// in the default component locations
        /// </summary>
        KernelResult Manage();

        /// <summary>
        /// Convenience method to load, initialise and start the components found in the indicated component locations
        /// </summary>
        /// <param name="componentLocations">file locations of the folder containing the components</param>
        /// <returns></returns>
        KernelResult Manage(string[] componentLocations);

        /// <summary>
        /// Starts all the components
        /// Default method used for invocation is 'Start'
        /// Methods must have this signature 'public void Start()'
        /// </summary>
        /// <returns></returns>
        KernelResult Start();

        /// <summary>
        /// Stops all the components
        /// Default method used for invocation is 'Stop'
        /// Methods must have this signature 'public void Stop()'
        /// </summary>
        /// <returns></returns>
        KernelResult Stop();

        #endregion Methods
    }
}